package lwk.forkjoin;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveTask;

/**
 * @author:lwk
 * @create: 2022-08-19 22:15
 * @Description: ForkJoin
 *
 * ForkJoinTask代表运行在ForkJoinPool中的任务。
 * 主要方法：
 * fork() 在当前线程运行的线程池中安排一个异步执行。简单的理解就是再创建一个子任务。
 * join() 当任务完成的时候返回计算结果。
 * invoke() 开始执行任务，如果必要，等待计算完成。
 * 子类： Recursive ：递归
 * RecursiveAction 一个递归无结果的ForkJoinTask（没有返回值）
 * RecursiveTask 一个递归有结果的ForkJoinTask（有返回值）
 */
public class ForkJoinDemo extends RecursiveTask<Long> {

    private final long start;//起始值
    private final long end;//结束值
    public static final long critical = 10000000L;//临界值
    public ForkJoinDemo(long start, long end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Long compute() {
        //判断是否是拆分完毕
        long lenth = end - start;
        if(lenth<=critical){
            //如果拆分完毕就相加
            long sum = 0L;
            for (long i = start;i<=end;i++){
                sum += i;
            }
            return sum;
        } else {
            //没有拆分完毕就开始拆分
            //计算的两个值的中间值
            long avg = (end + start) / critical;

            List<ForkJoinDemo> forkList = new ArrayList<>();
            for (long i = 0; i < avg; i++) {
                ForkJoinDemo right = new ForkJoinDemo(critical * i,critical * (i + 1));
                right.fork();//拆分，并压入线程队列
                forkList.add(right);
            }
            //合并
            return forkList.stream().mapToLong(ForkJoinTask::join).sum();
        }
    }
}
